home *** CD-ROM | disk | FTP | other *** search
- #include "lisp.h"
- #include "loader.h"
-
- /*
- When you set project preferences, you should
- fill in the dialog fields in the following way:
-
- Project Type -> 'Code Resource'
- Code Resource Info:
- File Name -> The name of your resource file (as expected by DEFCMODULE)
- Sym Name -> As you wish
- Resource name -> The name of your module (as expected by DEFCMODULE)
- Header Type -> 'Standard'
- Multi-Segment -> Checked ResType ResId
- Display Dialog -> As you wish 'TCCD' Any
- Merge to File -> As you wish Creator Type
- Any Any
-
- Resource Flags: Locked
- */
-
- /*
- CodeWarrior returns long values in D0 and pointers
- in A0 which is fine for MCL.
- */
-
- /*
- When MCL passes a Lisp object, it passes a pointer to it.
- That's why you need to use the GET macro to get to the actual Lisp object.
-
- MCL's fixnums are shifted by 3 bits (we say they are boxed).
- That's why you need to use to UNBOX macro to get the actual value.
-
- When you return a value (in D0), you don't need to BOX it first, as MCL
- will do it for you when your FF-CALL exits.
- */
-
- long testFixnum (long ptr)
- {
- return(UNBOX(GET(ptr)) + 1);
- }
-
- long testCharacter (long ptr)
- {
- switch (CHARACTER(GET(ptr))) {
- case 'a': return 1; break;
- case 'b': return 2; break;
- case 'c': return 3; break;
- default: return 4;
- }
- }
-
- void testList (long ptr)
- {
- long list = GET(ptr);
-
- CAR(list) += 8;
- CDR(list) = CDR(CDR(list));
- }
-
- struct foo {
- long a, b, c;
- };
-
- void testStruct (long ptr)
- {
- struct foo *s = STRUCTURE(GET(ptr),foo);
-
- /*
- As we are playing behind MCL's back, we need to BOX our integers.
- */
-
- s->a += BOX(1);
- s->b += BOX(2);
- s->c += BOX(3);
- }
-
- /*
- Passing multi-dimentionnal arrays to C would be
- very awkward because MCL implements multi-dimentionnal
- arrays as displaced arrays.
- */
-
- void testVector (long ptr)
- {
- int i;
- long *vec = VECTOR(GET(ptr));
-
- for(i=0; i<5; i++) {
- vec[i] += BOX(i);
- }
- }
-
- /*
- A string is simply a vector of characters,
- each one taking one byte of memory.
- */
-
- void testString (long ptr)
- {
- int i;
- char *str = STRING(GET(ptr));
-
- for(i=0; i<STRING_SIZE(GET(ptr)); i++) {
- if (str[i] == 'a')
- str[i] = 'A';
- }
- }
-
- void testShortDouble (long ptr)
- {
- short double *x = FLOAT(GET(ptr));
- *x = *x + 1.2;
- }
- /*
- I leave it to someone else to figure out long doubles - RGP
- */
-
- /*
- If you allocate your structures 'a la' C, then your C code
- becomes very nice and efficient (but see the THOUGHTS file for drawbacks).
- */
-
- struct myStruct {
- long a, b, c;
- };
-
- void testCStructures (struct myStruct *ptr)
- {
- ptr->c += ptr->a + ptr->b;
- }
-
- /*
- Unlike ThinkC, CW returns pointers via A0.
- */
-
- void *testA0 (char *ptr)
- {
- return (ptr+1);
- }
-
- long testCallback (long ptr, void (*lispfn) ())
- {
- (*lispfn) ();
- return(UNBOX(CAR(GET(ptr))));
- }
-
- long myLong = 11;
- short double sd = 0.23;
- double myDouble = 0.23;
-
- long testGlobals ()
- {
- return( myLong * myLong );
- }
-
-
- extern testMultiSegment();
-
- void *testTraps()
- {
- return NewPtr(12);
- }
-
- /*
- If the names match, the EXPORT macro returns the
- address of the function in the A0 register.
-
- If no EXPORT is successfull then the LOADER_ERROR
- macro returns a NIL pointer in A0.
- */
-
- void* main (unsigned char name[])
- {
- LOADER_INIT(name);
-
- EXPORT(name, myLong, "\pMY-LONG");
- EXPORT(name, myDouble, "\pMY-DOUBLE");
-
- EXPORT(name, testFixnum, "\pTEST-FIXNUM");
- EXPORT(name, testCharacter, "\pTEST-CHARACTER");
- EXPORT(name, testList, "\pTEST-LIST");
- EXPORT(name, testStruct, "\pTEST-STRUCT");
- EXPORT(name, testVector, "\pTEST-VECTOR");
- EXPORT(name, testString, "\pTEST-STRING");
- EXPORT(name, testShortDouble, "\pTEST-SHORT-DOUBLE");
- EXPORT(name, testCStructures, "\pTEST-C-STRUCTURES");
- EXPORT(name, testA0, "\pTEST-A0");
- EXPORT(name, testCallback, "\pTEST-CALLBACK");
- EXPORT(name, testGlobals, "\pTEST-GLOBALS");
- EXPORT(name, testMultiSegment, "\pTEST-MULTI-SEGMENT");
- EXPORT(name, testTraps, "\pTEST-TRAPS");
-
- LOADER_ERROR();
- }
-